package com.tanker.common.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.util.StringUtils;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;


/** 
 * @comments
 * @author  zg 
 * @version 创建时间：2014年6月4日
 */
public class AreaUtil {
	private static Logger logger = LoggerFactory.getLogger(AreaUtil.class);
	
	private static final String GET_BIZ_AREA_URL = "http://api.map.baidu.com/geocoder/v2/?ak=03c191741fa52a27375ba9684e7b0970&callback=renderReverse&output=json&pois=1&location=";
	
	public static String getBizArea(String lon, String lat){
		String bizArea = null;
		try {
			String url = GET_BIZ_AREA_URL + lat + "," + lon;
			StringBuilder resStr = sendGetRequest(url);
			int bizIdx = resStr.indexOf("\"business\":");
			if(bizIdx == -1){
				return "";
			}
			int idx = bizIdx + 12;
			resStr = resStr.delete(0,idx);
			idx = resStr.indexOf("\"");
			bizArea = resStr.substring(0,idx);
		} catch (Exception e) {
			logger.error("",e);
			bizArea = "";
		}
		return bizArea;
	}
	/**
	 * 该方法能获取json字符串中addressComponent中的属性对应的值
	 * 
	 * @param obj(key 为city 或者 province)
	 * @param lon
	 * @param lat
	 * @return
	 * @throws Exception
	 */
	public static String getObjString(String obj,String lon, String lat) throws Exception{
		 String resStr=sendGetRequest
				 ("http://api.map.baidu.com/geocoder/v2/?ak=03c191741fa52a27375ba9684e7b0970&output=json&location="+lat+","+lon,2000,2000).toString();
		 JSONObject jsonObject=JSONObject.fromObject(resStr);
		 Map map=new HashMap();
		 map=(Map) jsonObject.get("result");
		 map=(Map) map.get("addressComponent");
		return map.get(obj)==null?"":map.get(obj).toString();
	}
	public static String[] getBizAreas(String lon, String lat){
		String area = getBizArea(lon, lat);
		if(!StringUtils.hasText(area)){
			return null;
		}
		return area.split(",");
	}
	/**
	 * 根据ip获取当前的城市或者省份  
	 * key 为city 或者 province
	 * @param obj(key 为city 或者 province)
	 * @param ip
	 * @return
	 * @throws Exception
	 */
	public static String getObjString(String obj,String ip) throws Exception{
		String reString=sendGetRequest("http://api.map.baidu.com/location/ip?ak=03c191741fa52a27375ba9684e7b0970&ip="+ip+"&coor=bd09ll",2000,2000);
		JSONObject jsonObject =JSONObject.fromObject(reString);
		Map map=(Map) jsonObject.get("content");
		map=(Map) map.get("address_detail");
		return (String) map.get(obj)==null?"":(String) map.get(obj);
	}
	
	public static String getReqAddrFromLonLat(String lon, String lat){
		try {
			//第一步：根据高德的经纬度转换成百度的经纬度。
			String reString=sendGetRequest("http://api.map.baidu.com/geoconv/v1/?coords="+lon+","+lat+"&from=3&to=5&ak=aBQ9e7D7XhKnMbnbWwER96m1", 2000,2000);
			JSONObject json=JSONObject.fromObject(reString);
			
			if((Integer)json.get("status") != 0){
	 			return "mistakeLonLat";
	 		}
			
			List list=(List) json.get("result");
			Map map= (Map) list.get(0);
			lon = String.valueOf(map.get("x"));  //Double类型转换为String
			lat = String.valueOf(map.get("y"));  //Double类型转换为String
			
			//根据百度的经纬度查询地址。
			String resStr=sendGetRequest("http://api.map.baidu.com/geocoder/v2/?ak=03c191741fa52a27375ba9684e7b0970&output=json&location="+lat+","+lon,2000,2000).toString();
			JSONObject jsonObject=JSONObject.fromObject(resStr);
			if((Integer)jsonObject.get("status") != 0){
				return "mistakeGetAddr";
		 	}
			
			map.clear();
			map=(Map) jsonObject.get("result");
			return map.get("formatted_address")==null?"":map.get("formatted_address").toString();
		} catch (Exception e) {
			return "mistakeError";
		}
	}
	/**
	 * 百度接口
	 * 该方法能获取json字符串中addressComponent中的属性对应的值
	 * 
	 * @param obj(key 为city 或者 province)
	 * @param lon
	 * @param lat
	 * @return
	 * @throws Exception
	 */
	public static Map<String, String> getPlaceFromBMap(String lon, String lat) throws Exception{
		 String resStr=sendGetRequest
				 ("http://api.map.baidu.com/geocoder/v2/?ak=03c191741fa52a27375ba9684e7b0970&output=json&location="+lat+","+lon,2000,2000).toString();
		 JSONObject jsonObject=JSONObject.fromObject(resStr);
		 Map<String,String>  resultMap=new HashMap<String,String>();
			 Map map=new HashMap();
			 map=(Map) jsonObject.get("result");
			 map=(Map) map.get("addressComponent");
			 resultMap.put("city", String.valueOf(map.get("city")));
			 resultMap.put("province", String.valueOf(map.get("province")));
		return resultMap;
	}
	
	/**
	 * 高德接口
	 * @param lon 经度
	 * @param lat 纬度	
	 * @return 返回的Map(key 为city 或者 province)
	 * @throws Exception
	 */
	public static String getAddressFromAMap(double lon, double lat) throws Exception{
		 String address = "";
		 String resStr=sendGetRequest
				 ("http://restapi.amap.com/v3/geocode/regeo?output=json&location="+lon+","+lat+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base",2000,2000).toString();
		 //logger.info("经纬度信息及地址:"+resStr+"  "+lon+","+lat);
		 if(StringUtils.hasText(resStr))
		 {
			 JSONObject jsonObject=JSONObject.fromObject(resStr);
			 JSONObject jsonRegeocode = jsonObject.getJSONObject("regeocode");

			 if(jsonRegeocode!=null)
			 {
				  address = jsonRegeocode.getString("formatted_address");
			 }
		 }
		 return address;
	}
	
	/**
	 * 高德接口 街道地址
	 * @param lon
	 * @param lat
	 */
	public static String getStreetFromAMap(double lon, double lat) throws Exception{
		Map<String, String> resultMap=new HashMap<String, String>();
		 String resStr=sendGetRequest
				 ("http://restapi.amap.com/v3/geocode/regeo?output=json&location="+lon+","+lat+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base",2000,2000).toString();

		 String str = "";
		 if(StringUtils.hasText(resStr))
		 {
			 JSONObject jsonObject=JSONObject.fromObject(resStr);
			 JSONObject jsonRegeocode = jsonObject.getJSONObject("regeocode");

			 if(jsonRegeocode!=null)
			 {
				 JSONObject addressJson=  jsonRegeocode.getJSONObject("addressComponent");
				 if(addressJson!=null){
					 JSONObject streetNumber =  addressJson.getJSONObject("streetNumber");
					 if(streetNumber!=null) {
						 String street = streetNumber.getString("street");
						 String number = streetNumber.getString("number");
						 if(street!=null) {
							 str = str + street;
							 if(number!=null)
								 str = str + number;
						 }
					 }
				 }
			 }
		 }
		 return str;
	}
	
	/**
	 * 高德接口 附近停车点(非免费)
	 * @param lon
	 * @param lat
	 */
	public static List<Map<String, String>> getNearByParkFromAMap(double lon, double lat) throws Exception{
		 String resStr=sendGetRequest("http://restapi.amap.com/v3/place/around?output=json&location="+lon+","+lat+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&types=150900&radius=50&sortrule=distance&extensions=base",2000,2000).toString();

		 List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		 if(StringUtils.hasText(resStr))  {
			 JSONObject jsonObject=JSONObject.fromObject(resStr);
			 JSONArray array = jsonObject.getJSONArray("pois");

			 if(array!=null) {
				 Map<String, String> map = null;
				 for(int i=0; i<array.size(); i++) {
					 JSONObject obj = JSONObject.fromObject(array.get(i));
					 if(obj!=null) {
						 map = new HashMap<String, String>();
						 map.put("name", obj.getString("name"));
						 map.put("address", obj.getString("address"));
						 String location = obj.getString("location");
						 if(location!=null) {
							 String[] strs = location.split(",");
							 if(strs!=null && strs.length==2) {
								 map.put("lon", strs[0]);
								 map.put("lat", strs[1]);
							 }
						 }
						 list.add(map);
						 if(list.size()==4)
							 break;
					 }
				 }
			 }
		 } 
		 return list;
	}
	/**
	 * 高德接口
	 * @param lon 经度
	 * @param lat 纬度	
	 * @return 返回的Map(key 为city 或者 province)
	 * @throws Exception
	 */
	public static Map<String, String> getPlaceFromAMap(double lon, double lat) throws Exception{
		Map<String, String> resultMap=new HashMap<String, String>();
		 String resStr=sendGetRequest
				 ("http://restapi.amap.com/v3/geocode/regeo?output=json&location="+lon+","+lat+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base",2000,2000).toString();
		 //logger.info("经纬度信息及地址:"+resStr+"  "+lon+","+lat);
		 if(StringUtils.hasText(resStr))
		 {
			 JSONObject jsonObject=JSONObject.fromObject(resStr);
			 JSONObject jsonRegeocode = jsonObject.getJSONObject("regeocode");

			 if(jsonRegeocode!=null)
			 {
				 JSONObject addressJson=  jsonRegeocode.getJSONObject("addressComponent");
				 if(addressJson!=null){
					 resultMap.put("city", addressJson.getString("city"));


					 resultMap.put("province",  addressJson.getString("province"));
				 }
			 }
		 }
		 return resultMap;
	}
	
	/**
	 * 行政区域查询经纬度范围
	 * @param cityCode
	 * @return
	 * @throws Exception
	 */
	public static List<Map<String, Double>> getDistrictPoints(String cityCode) throws Exception{
		String resStr = sendGetRequest
				("http://restapi.amap.com/v3/config/district?key=5ac4c2e00b7fb4e43acbf68fffd87e3f&keywords="+cityCode+"&level=city&subdistrict=0&extensions=all",2000,2000).toString();
		List<Map<String, Double>> polygonPoints = new ArrayList<Map<String, Double>>();
		if(StringUtils.hasText(resStr)){
			JSONObject jsonObject=JSONObject.fromObject(resStr);
			JSONArray jsonRegeocode = jsonObject.getJSONArray("districts");
			JSONObject object = JSONObject.fromObject(jsonRegeocode.get(0));
			String lonAndLatStr =  object.get("polyline").toString();
			if (StringUtils.isEmpty(lonAndLatStr)) {
				return polygonPoints;
			}
			String[] lonAndLats = lonAndLatStr.split(";");
			for (String lonAndLat : lonAndLats) {
				if (lonAndLat.indexOf("|")>=0) {//处理返回的特殊字符
					String[] str = lonAndLat.split("\\|");
					Map<String, Double> lonAndLatMap = new HashMap<String, Double>();
					String s = str[0];
					String lon = s.split(",")[0];
					String lat = s.split(",")[1];
					lonAndLatMap.put("lon", Double.parseDouble(lon));
					lonAndLatMap.put("lat", Double.parseDouble(lat));
					polygonPoints.add(lonAndLatMap);
					lonAndLatMap = new HashMap<String, Double>();
					lon = str[1].split(",")[0];
					lat = str[1].split(",")[1];
					lonAndLatMap.put("lon", Double.parseDouble(lon));
					lonAndLatMap.put("lat", Double.parseDouble(lat));
					polygonPoints.add(lonAndLatMap);
				}else{
					Map<String, Double> lonAndLatMap = new HashMap<String, Double>();
					String lon = lonAndLat.split(",")[0];
					String lat = lonAndLat.split(",")[1];
					lonAndLatMap.put("lon", Double.parseDouble(lon));
					lonAndLatMap.put("lat", Double.parseDouble(lat));
					polygonPoints.add(lonAndLatMap);
				}
			}
		}
		return polygonPoints;
	}
	/**高德接口 导航路径
	 * 求距离
	 * @param sLon ：起点经度
	 * @param sLat：起点纬度
	 * @param eLon：终点经度
	 * @param eLat终点纬度
	 * @param type：0：速度优先（时间）；1：费用优先（不走收费路段的最快道路）；2：距离优先；3：不走快速路；4：躲避拥堵；5：多策略（同时使用速度优先、费用优先、距离优先三个策略计算路径）；6：不走高速7不走高速且避免收费；8：躲避收费和拥堵；9：不走高速且躲避收费和拥堵 
	 * @return：返回距离单位为米
	 * @throws Exception
	 */
	
	public static Long getPdirectionMap(double sLon, double sLat,double eLon, double eLat,int type) throws Exception{
		try {	
		String url="http://restapi.amap.com/v3/direction/driving?output=json&origin="+sLon+","+sLat+"&destination="+eLon+","+eLat+"&strategy="+type+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base";
//		String url="http://restapi.amap.com/v3/direction/driving?origin=116.481028,39.989643&destination=116.465302,40.004717&extensions=base&output=json&key=5ac4c2e00b7fb4e43acbf68fffd87e3f";
		String resStr=sendGetRequest(url,2000,2000).toString();
		System.out.println(resStr);
		if(StringUtils.hasText(resStr))
		{
			JSONObject jsonObject=JSONObject.fromObject(resStr);
			JSONObject jsonroute = jsonObject.getJSONObject("route");
			if(jsonroute!=null)
			{
				JSONArray	pathsJson=jsonroute.getJSONArray("paths");
				if(pathsJson!=null){
					JSONObject pathObjectJson=pathsJson.getJSONObject(0);
					if (pathObjectJson!=null) {
						return pathObjectJson.getLong("distance");
					}
					
				}
			}
		}
		} catch (Exception e) {
			logger.error("调高德获取距离出错",e);
		}
		return null;
	}
	/**
	 * 计算距离
	 *@param sLon ：起点经度
	 * @param sLat：起点纬度
	 * @param eLon：终点经度
	 * @param eLat终点纬度
	 * @param type：0：速度优先（时间）；1：费用优先（不走收费路段的最快道路）；2：距离优先；3：不走快速路；4：躲避拥堵；5：多策略（同时使用速度优先、费用优先、距离优先三个策略计算路径）；6：不走高速7不走高速且避免收费；8：躲避收费和拥堵；9：不走高速且躲避收费和拥堵 
	 * @return
	 */
	public static Float getCarDistance(Double sLon, Double sLat, Double eLon,
			Double eLat,int type) {
		Long distance=null;
			try {
				 distance = AreaUtil.getPdirectionMap(sLon, sLat, eLon, eLat, type);
				if (distance == null) {
					for (int i = 0; i < 3; i++) {
						distance = AreaUtil.getPdirectionMap(sLon, sLat, eLon, eLat,
								type);
						if (distance != null) {
							break;
						}
					}
				}
				if (distance==null) {
					logger.error("高德地图异常：用默认距离80，sLon={},sLat={},eLon={},eLat={},type={}",sLon,sLat,eLon,eLat,type);
					return null;
				}else {
					float realDistance=distance/100f;
					return Math.round(realDistance)/10f;
				}
			} catch (Exception e) {
				logger.error("计算距离出错",e);
			}
			
		return null;
	}
	
	/**
	 * 根据ip获取当前的城市或者省份  
	 * @param ip
	 * @return 返回的Map(key 为city 或者 province)
	 * @throws Exception
	 */
	public static Map<String,String> getPlaceFromBMap(String ip) throws Exception{
		String reString=sendGetRequest("http://api.map.baidu.com/location/ip?ak=03c191741fa52a27375ba9684e7b0970&ip="+ip+"&coor=bd09ll",10000,8000);
		JSONObject jsonObject =JSONObject.fromObject(reString);
		Map map=(Map) jsonObject.get("content");
		map=(Map) map.get("address_detail");
		Map<String,String>  resultMap=new HashMap<String,String>();
		resultMap.put("city", String.valueOf(map.get("city")));
		resultMap.put("province", String.valueOf(map.get("province")));
		return resultMap;
	}
	
	private static StringBuilder sendGetRequest(String reqUrl) throws Exception{
		logger.info("查询商圈：{}",reqUrl);
		URL url = new URL(reqUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		BufferedReader bin = null;
		StringBuilder sb = null;
		try {
			conn.setConnectTimeout(10000);
			conn.setReadTimeout(8000);
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			conn.connect();
			InputStream in = conn.getInputStream();
			bin = null;
			int resCode = conn.getResponseCode();
			sb = new StringBuilder();
			if (resCode == 200) {
				bin = new BufferedReader(new InputStreamReader(in,"UTF-8"));
				String line = null;
				while ((line = bin.readLine()) != null) {
					sb.append(line);
				}
			}else{
				logger.error("获取“商圈”错误，ResponseCode:{}",resCode);
			}
		} catch (Exception e) {
			logger.error("",e);
		} finally{
			conn.disconnect();
			if(bin != null){
				bin.close();
			}
		}
		logger.info("查询商圈返回：{}",sb);
		return sb;
	}

	private static String sendGetRequest(String reqUrl,int connectOutTime,int readOutTime) throws Exception{
		URL url = new URL(reqUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(connectOutTime);
		conn.setReadTimeout(readOutTime);
		conn.setDoInput(true);
		conn.setRequestMethod("GET");
		conn.connect();
		InputStream in = conn.getInputStream();
		BufferedReader bin = null;
		int resCode = conn.getResponseCode();
		StringBuilder sb = new StringBuilder();
		if (resCode == 200) {
			bin = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String line = null;
			while ((line = bin.readLine()) != null) {
				sb.append(line);
			}
		}else{
			logger.error("获取地址错误，ResponseCode:{}",resCode);
		}
		if(bin != null){
			bin.close();
		}
		return sb.toString();
	}
	public static void main(String[] args) throws Exception{
		//System.out.println(Arrays.toString(getDistrictLonAndLatStr("310000").split(";")));//凉城,广中路,江湾
		//origin=116.481028,39.989643&destination=116.465302,40.004717
//		Long n=getPdirectionMap(121.432365,31.196225,123.432365,36.196225,0);
		
//		 List<Map<String, Double>> polygonPoints =  BizAreaUtil.getDistrictPoints("310000");
//	 31.193266  121.321492
//		   System.out.println( GeoUtils.isPointInPolygon(121.432365,31.196225, polygonPoints));;
		//Long n=getPdirectionMap(121.436525,31.188523,121.321492,31.193266,2);
		/*String lanLant=	getlonLatFromAMap("上海市浦东新区陆家嘴环路1288号");
		String[] f=lanLant.split(",");
		for (String string : f) {
			System.out.println(string);
		}*/
		 //Map<String, String> map = getPlaceFromAMap(121.321492,31.193266);
		//String str = getAddressFromAMap(120.610624,31.293790);
		//System.out.println(str);
		getNearByParkFromAMap(121.43243,31.19593);
	}
	
	/**
	 * 高德接口
	 * @param lon 经度
	 * @param lat 纬度	
	 * @return 返回的Map(key 为city 或者 province)
	 * @throws Exception
	 */
	public static String getlonLatFromAMap(String key) throws Exception{
		String address = "";
		try {
		
//		 String resStr=sendGetRequest
//				 ("http://restapi.amap.com/v3/geocode/regeo?output=json&location="+lon+","+lat+"&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base",2000,2000).toString();
		 String resStr=sendGetRequest
				 ("http://restapi.amap.com/v3/place/text?&keywords="+key+"&city=上海&output=json&offset=20&page=1&key=5ac4c2e00b7fb4e43acbf68fffd87e3f&extensions=base",2000,2000).toString();
		 //logger.info("经纬度信息及地址:"+resStr+"  "+lon+","+lat);
		 if(StringUtils.hasText(resStr))
		 {
			 JSONObject jsonObject=JSONObject.fromObject(resStr);
			 if (jsonObject!=null) {
				 JSONArray jsonRegeocode = jsonObject.getJSONArray("pois");
				 if (jsonRegeocode!=null) {
					 
					 JSONObject object = JSONObject.fromObject(jsonRegeocode.get(0));
					 address =  object.get("location").toString();
				 }
			}

		 }
		} catch (Exception e) {
			logger.error("sss",e);
		}
		 return address;
	}
}
 
